home *** CD-ROM | disk | FTP | other *** search
/ Kit PC World De Ampliacion De Windows 95 / Kit PC World de ampliacion de Windows 95.iso / internet / sweeper / samples / olecon~1 / framewrk / ctlpsst.cpp < prev    next >
Text File  |  1995-11-25  |  17KB  |  661 lines

  1. //=--------------------------------------------------------------------------=
  2. // ControlPersistence.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright  1995  Microsoft Corporation.  All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // implementation of persistence interfaces for COleControl.
  13. //
  14. #include "IPServer.H"
  15. #include "CtrlObj.H"
  16.  
  17. #include "CtlHelp.H"
  18. #include "Util.H"
  19.  
  20. // this is the name of the stream we'll save our ole controls to.
  21. //
  22. WCHAR wszCtlSaveStream [] = L"CONTROLSAVESTREAM";
  23.  
  24.  
  25. // for ASSERT and FAIL
  26. //
  27. SZTHISFILE
  28.  
  29.  
  30. //=--------------------------------------------------------------------------=
  31. // to help with out stream save implementation ...
  32. //
  33. #define STREAMHDR_SIGNATURE 0x12344321  // Signature to identify our format (avoid crashes!)
  34. #define IPROP_END 0xFF                  // Marker at end of property list
  35. #define MAXAUTOBUF 3800                 // Best if < 1 page.
  36.  
  37. typedef struct tagSTREAMHDR {
  38.  
  39.     DWORD  dwSignature;     // Signature.
  40.     size_t cbWritten;       // Number of bytes written
  41.  
  42. } STREAMHDR;
  43.  
  44. //=--------------------------------------------------------------------------=
  45. // COleControl persistence interfaces
  46. //=--------------------------------------------------------------------------=
  47.  
  48.  
  49. //=--------------------------------------------------------------------------=
  50. // COleControl::Load    [IPersistPropertyBag]
  51. //=--------------------------------------------------------------------------=
  52. // IPersistPropertyBag.  we've got a property bag, so let's load our properties
  53. // from it.
  54. //
  55. // Parameters:
  56. //    IPropertyBag *      - [in] pbag from which to read props.
  57. //    IErrorLog *         - [in] error log to write to
  58. //
  59. // Output:
  60. //    HRESULT
  61. //
  62. // Notes:
  63. //
  64. STDMETHODIMP COleControl::Load
  65. (
  66.     IPropertyBag *pPropertyBag,
  67.     IErrorLog    *pErrorLog
  68. )
  69. {
  70.     HRESULT hr;
  71.  
  72.     // load in our standard state first.  nothing serious here ... currently,
  73.     // we've just got two properties, for cx and cy.
  74.     //
  75.     hr = LoadStandardState(pPropertyBag, pErrorLog);
  76.     RETURN_ON_FAILURE(hr);
  77.  
  78.     // now call the user text load function, and get them to load in whatever
  79.     // they're interested in.
  80.     //
  81.     hr = LoadTextState(pPropertyBag, pErrorLog);
  82.  
  83.     return hr;
  84. }
  85.  
  86. //=--------------------------------------------------------------------------=
  87. // COleControl::Save    [IPersistPropertyBag]
  88. //=--------------------------------------------------------------------------=
  89. // given a property bag, save out all the relevant state information.
  90. //
  91. // Parameters:
  92. //    IPropertyBag *        - [in] property to write to
  93. //    BOOL                  - [in] do we clear the dirty bit?
  94. //    BOOL                  - [in] do we write out default values anyhoo?
  95. //
  96. // Output:
  97. //    HRESULT
  98. //
  99. // Notes:
  100. //
  101. STDMETHODIMP COleControl::Save
  102. (
  103.     IPropertyBag *pPropertyBag,
  104.     BOOL          fClearDirty,
  105.     BOOL          fWriteDefault
  106. )
  107. {
  108.     HRESULT hr;
  109.  
  110.     // save out standard state information
  111.     //
  112.     hr = SaveStandardState(pPropertyBag);
  113.     RETURN_ON_FAILURE(hr);
  114.  
  115.     // now call the user function and get them to save out
  116.     // all of their properties.
  117.     //
  118.     hr = SaveTextState(pPropertyBag, fWriteDefault);
  119.     RETURN_ON_FAILURE(hr);
  120.  
  121.     // now clear the dirty flag and send out notification that we're
  122.     // done.
  123.     //
  124.     if (fClearDirty)
  125.         m_fDirty = FALSE;
  126.  
  127.     if (m_pOleAdviseHolder)
  128.         m_pOleAdviseHolder->SendOnSave();
  129.  
  130.     return S_OK;
  131. }
  132.  
  133. //=--------------------------------------------------------------------------=
  134. // COleControl::GetClassID    [IPersistStreamInit]
  135. //=--------------------------------------------------------------------------=
  136. // returns the classid of this mamma
  137. //
  138. // Parameters:
  139. //    CLSID *         - [out] where to put the clsid
  140. //
  141. // Output:
  142. //    HRESULT
  143. //
  144. // Notes:
  145. //
  146. STDMETHODIMP COleControl::GetClassID
  147. (
  148.     CLSID *pclsid
  149. )
  150. {
  151.     CHECK_POINTER(pclsid);
  152.  
  153.     // copy the thing over
  154.     //
  155.     *pclsid = CLSIDOFOBJECT(m_ObjectType);
  156.     return S_OK;
  157. }
  158.  
  159.  
  160. //=--------------------------------------------------------------------------=
  161. // COleControl::IsDirty    [IPersistStreamInit]
  162. //=--------------------------------------------------------------------------=
  163. // asks if we're dirty or not.  duh.
  164. //
  165. // Output:
  166. //    HRESULT        - S_OK: dirty, S_FALSE: not dirty
  167. //
  168. // Notes:
  169. //
  170. STDMETHODIMP COleControl::IsDirty
  171. (
  172.     void
  173. )
  174. {
  175.     return (m_fDirty) ? S_OK : S_FALSE;
  176. }
  177.  
  178. //=--------------------------------------------------------------------------=
  179. // COleControl::InitNew    [IPersistStreamInit]
  180. //=--------------------------------------------------------------------------=
  181. // causes the control to intialize itself with a new bunch of state information
  182. //
  183. // Output:
  184. //    HRESULT
  185. //
  186. // Notes:
  187. //
  188. STDMETHODIMP COleControl::InitNew
  189. (
  190.     void
  191. )
  192. {
  193.     BOOL f;
  194.  
  195.     // call the overridable function to do this work
  196.     //
  197.     f = InitializeNewState();
  198.     return (f) ? S_OK : E_FAIL;
  199. }
  200.  
  201. //=--------------------------------------------------------------------------=
  202. // COleControl::GetSizeMax    [IPersistStreamInit]
  203. //=--------------------------------------------------------------------------=
  204. //
  205. // Parameters:
  206. //    ULARGE_INTEGER *    - [out]
  207. //
  208. // Output:
  209. //    HRESULT
  210. //
  211. // Notes:
  212. //
  213. STDMETHODIMP COleControl::GetSizeMax
  214. (
  215.     ULARGE_INTEGER *pulMaxSize
  216. )
  217. {
  218.     return E_NOTIMPL;
  219. }
  220.  
  221. //=--------------------------------------------------------------------------=
  222. // COleControl::Load    [IPersistStreamInit]
  223. //=--------------------------------------------------------------------------=
  224. // load from an IStream
  225. //
  226. // Parameters:
  227. //    IStream *    - [in] stream from which to load
  228. //
  229. // Output:
  230. //    HRESULT
  231. //
  232. // Notes:
  233. //
  234. STDMETHODIMP COleControl::Load
  235. (
  236.     IStream *pStream
  237. )
  238. {
  239.     HRESULT hr;
  240.  
  241.     // first thing to do is read in standard properties the user don't
  242.     // persist themselves.
  243.     //
  244.     hr = LoadStandardState(pStream);
  245.     RETURN_ON_FAILURE(hr);
  246.  
  247.     // load in the user properties.  this method is one they -have- to implement
  248.     // themselves.
  249.     //
  250.     hr = LoadBinaryState(pStream);
  251.     
  252.     return hr;
  253. }
  254.  
  255. //=--------------------------------------------------------------------------=
  256. // COleControl::Save    [IPersistStreamInit]
  257. //=--------------------------------------------------------------------------=
  258. // saves out our state using streams
  259. //
  260. // Parameters:
  261. //    IStream *        - [in]
  262. //    BOOL             - [in] clear dirty bit?
  263. //
  264. // Output:
  265. //    HRESULT
  266. //
  267. // Notes:
  268. //
  269. STDMETHODIMP COleControl::Save
  270. (
  271.     IStream *pStream,
  272.     BOOL     fClearDirty
  273. )
  274. {
  275.     HRESULT hr;
  276.  
  277.     // use our helper routine that we share with the IStorage persistence
  278.     // code.
  279.     //
  280.     hr = m_SaveToStream(pStream);
  281.     RETURN_ON_FAILURE(hr);
  282.  
  283.     // clear out dirty flag [if appropriate] and notify that we're done
  284.     // with save.
  285.     //
  286.     if (fClearDirty)
  287.         m_fDirty = FALSE;
  288.     if (m_pOleAdviseHolder)
  289.         m_pOleAdviseHolder->SendOnSave();
  290.  
  291.     return S_OK;
  292. }
  293.  
  294. //=--------------------------------------------------------------------------=
  295. // COleControl::InitNew    [IPersistStorage]
  296. //=--------------------------------------------------------------------------=
  297. // ipersiststorage version of this.  fweee
  298. //
  299. // Parameters:
  300. //    IStorage *    - [in] we don't use this
  301. //
  302. // Output:
  303. //    HRESULT
  304. //
  305. // Notes:
  306. //
  307. STDMETHODIMP COleControl::InitNew
  308. (
  309.     IStorage *pStorage
  310. )
  311. {
  312.     // we already have an implementation of this [for IPersistStreamInit]
  313.     //
  314.     return InitNew();
  315. }
  316.  
  317. //=--------------------------------------------------------------------------=
  318. // COleControl::Load    [IPersistStorage]
  319. //=--------------------------------------------------------------------------=
  320. // Ipersiststorage version of this
  321. //
  322. // Parameters:
  323. //    IStorage *    - [in] DUH.
  324. //
  325. // Output:
  326. //    HRESULT
  327. //
  328. // Notes:
  329. //
  330. STDMETHODIMP COleControl::Load(IStorage *pStorage)
  331. {
  332.     IStream *pStream;
  333.     HRESULT  hr;
  334.  
  335.     // we're going to use IPersistStream::Load from the CONTENTS stream.
  336.     //
  337.     hr = pStorage->OpenStream(wszCtlSaveStream, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);
  338.     RETURN_ON_FAILURE(hr);
  339.  
  340.     // IPersistStreamInit::Load
  341.     //
  342.     hr = Load(pStream);
  343.     pStream->Release();
  344.     return hr;
  345. }
  346.  
  347. //=--------------------------------------------------------------------------=
  348. // COleControl::Save    [IPersistStorage]
  349. //=--------------------------------------------------------------------------=
  350. // save into the contents stream of the given storage object.
  351. //
  352. // Parameters:
  353. //    IStorage *        - [in] 10 points if you figure it out
  354. //    BOOL              - [in] is the storage the same as the load storage?
  355. //
  356. // Output:
  357. //    HRESULT
  358. //
  359. // Notes:
  360. //
  361. STDMETHODIMP COleControl::Save
  362. (
  363.     IStorage *pStorage,
  364.     BOOL      fSameAsLoad
  365. )
  366. {
  367.     IStream *pStream;
  368.     HRESULT  hr;
  369.  
  370.     // we're just going to save out to the CONTENTES stream.
  371.     //
  372.     hr = pStorage->CreateStream(wszCtlSaveStream, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
  373.                                 0, 0, &pStream);
  374.     RETURN_ON_FAILURE(hr);
  375.  
  376.     // use our helper routine.
  377.     //
  378.     hr = m_SaveToStream(pStream);
  379.     m_fSaveSucceeded = (FAILED(hr)) ? FALSE : TRUE;
  380.     pStream->Release();
  381.     return hr;
  382. }
  383.  
  384. //=--------------------------------------------------------------------------=
  385. // COleControl::SaveCompleted    [IPersistStorage]
  386. //=--------------------------------------------------------------------------=
  387. // lets us clear out our flags.
  388. //
  389. // Parameters:
  390. //    IStorage *    - ignored
  391. //
  392. // Output:
  393. //    HRESULT
  394. //
  395. // Notes:
  396. //
  397. STDMETHODIMP COleControl::SaveCompleted
  398. (
  399.     IStorage *pStorageNew
  400. )
  401. {
  402.     // if our save succeeded, then we can do our post save work.
  403.     //
  404.     if (m_fSaveSucceeded) {
  405.         m_fDirty = FALSE;
  406.         if (m_pOleAdviseHolder)
  407.             m_pOleAdviseHolder->SendOnSave();
  408.     }
  409.  
  410.     return S_OK;
  411. }
  412.  
  413. //=--------------------------------------------------------------------------=
  414. // COleControl::HandsOffStorage    [IPersistStorage]
  415. //=--------------------------------------------------------------------------=
  416. // not interesting
  417. //
  418. // Output:
  419. //    S_OK
  420. //
  421. // Notes:
  422. //
  423. STDMETHODIMP COleControl::HandsOffStorage
  424. (
  425.     void
  426. )
  427. {
  428.     // we don't ever hold on to  a storage pointer, so this is remarkably
  429.     // uninteresting to us.
  430.     //
  431.     return S_OK;
  432. }
  433.  
  434. //=--------------------------------------------------------------------------=
  435. // COleControl::m_SaveToStream    [helper: IPersistStreamInit/IPersistStorage]
  436. //=--------------------------------------------------------------------------=
  437. // save ourselves to a stream
  438. //
  439. // Parameters:
  440. //    IStream *        - figure it out
  441. //
  442. // Output:
  443. //    HRESULT
  444. //
  445. // Notes:
  446. //
  447. HRESULT COleControl::m_SaveToStream
  448. (
  449.     IStream *pStream
  450. )
  451. {
  452.     HRESULT hr;
  453.  
  454.     // save out standard state information that the user has no control
  455.     // over
  456.     //
  457.     hr = SaveStandardState(pStream);
  458.     RETURN_ON_FAILURE(hr);
  459.  
  460.     // save out user-specific satte information.  they MUST implement this
  461.     // function
  462.     //
  463.     hr = SaveBinaryState(pStream);
  464.  
  465.     return hr;
  466. }
  467.  
  468. //=--------------------------------------------------------------------------=
  469. // COleControl::LoadStandardState    [ helper ]
  470. //=--------------------------------------------------------------------------=
  471. // reads in standard properties that all controls are going to have, using
  472. // text persistence APIs.  there is another version for streams.
  473. //
  474. // Parameters:
  475. //    IPropertyBag *    - [in]
  476. //    IErrorLog *       - [in]
  477. //
  478. // Output:
  479. //    HRESULT
  480. //
  481. // Notes:
  482. //
  483. HRESULT COleControl::LoadStandardState
  484. (
  485.     IPropertyBag *pPropertyBag,
  486.     IErrorLog    *pErrorLog
  487. )
  488. {
  489.     VARIANT v;
  490.     HRESULT hr;
  491.     SIZEL   slHiMetric;
  492.  
  493.     // currently, our only standard properties are related to size.
  494.     //
  495.     v.vt = VT_I4;
  496.     v.lVal = 0;
  497.     hr = pPropertyBag->Read(L"_ExtentX", &v, pErrorLog);
  498.     CLEANUP_ON_FAILURE(hr);
  499.  
  500.     slHiMetric.cx = v.lVal;
  501.  
  502.     v.lVal = 0;
  503.     hr = pPropertyBag->Read(L"_ExtentY", &v, pErrorLog);
  504.     CLEANUP_ON_FAILURE(hr);
  505.  
  506.     slHiMetric.cy = v.lVal;
  507.  
  508.     HiMetricToPixel(&slHiMetric, &m_Size);
  509.     return hr;
  510.  
  511.   CleanUp:
  512.     memset(&m_Size, 0, sizeof(m_Size));
  513.     return hr;
  514. }
  515.  
  516. //=--------------------------------------------------------------------------=
  517. // COleControl::LoadStandardState    [ helper ]
  518. //=--------------------------------------------------------------------------=
  519. // reads in standard properties that all controls are going to have, using
  520. // stream persistence APIs.  there is another version for text.
  521. //
  522. // Parameters:
  523. //    IStream *         - [in] 
  524. //
  525. // Output:
  526. //    HRESULT
  527. //
  528. // Notes:
  529. //
  530. HRESULT COleControl::LoadStandardState
  531. (
  532.     IStream *pStream
  533. )
  534. {
  535.     STREAMHDR stmhdr;
  536.     HRESULT hr;
  537.     SIZEL   slHiMetric;
  538.  
  539.     // look for our header structure, so we can verify stream validity.
  540.     //
  541.     hr = pStream->Read(&stmhdr, sizeof(STREAMHDR), NULL);
  542.     RETURN_ON_FAILURE(hr);
  543.  
  544.     if (stmhdr.dwSignature != STREAMHDR_SIGNATURE)
  545.         return E_UNEXPECTED;
  546.  
  547.     // currently, the only standard state we're writing out is
  548.     // a SIZEL structure describing the control's size.
  549.     //
  550.     if (stmhdr.cbWritten != sizeof(m_Size))
  551.         return E_UNEXPECTED;
  552.  
  553.     // we like the stream.  let's go load in our two properties.
  554.     //
  555.     hr = pStream->Read(&slHiMetric, sizeof(slHiMetric), NULL);
  556.     RETURN_ON_FAILURE(hr);
  557.  
  558.     HiMetricToPixel(&slHiMetric, &m_Size);
  559.     return S_OK;
  560. }
  561.  
  562. //=--------------------------------------------------------------------------=
  563. // COleControl::SaveStandardState    [ helper ]
  564. //=--------------------------------------------------------------------------=
  565. // saves out standard properties that we're managing for a control using text
  566. // persistence APIs.  there is another version for stream persistence.
  567. //
  568. // Parameters:
  569. //    IPropertyBag *        - [in]
  570. //
  571. // Output:
  572. //    HRESULT
  573. //
  574. // Notes:
  575. //
  576. HRESULT COleControl::SaveStandardState
  577. (
  578.     IPropertyBag *pPropertyBag
  579. )
  580. {
  581.     HRESULT hr;
  582.     VARIANT v;
  583.     SIZEL   slHiMetric;
  584.  
  585.     // currently, the only standard proprerties we persist are Size related
  586.     //
  587.     PixelToHiMetric(&m_Size, &slHiMetric);
  588.  
  589.     v.vt = VT_I4;
  590.     v.lVal = slHiMetric.cx;
  591.  
  592.     hr = pPropertyBag->Write(L"_ExtentX", &v);
  593.     RETURN_ON_FAILURE(hr);
  594.  
  595.     v.lVal = slHiMetric.cy;
  596.  
  597.     hr = pPropertyBag->Write(L"_ExtentY", &v);
  598.  
  599.     return hr;
  600. }
  601.  
  602. //=--------------------------------------------------------------------------=
  603. // COleControl::SaveStandardState    [ helper ]
  604. //=--------------------------------------------------------------------------=
  605. // saves out standard properties that we're managing for a control using stream
  606. // persistence APIs.  there is another version for text persistence.
  607. //
  608. // Parameters:
  609. //    IStream *            - [in]
  610. //
  611. // Output:
  612. //    HRESULT
  613. //
  614. // Notes:
  615. //
  616. HRESULT COleControl::SaveStandardState
  617. (
  618.     IStream *pStream
  619. )
  620. {
  621.     STREAMHDR streamhdr = { STREAMHDR_SIGNATURE, sizeof(SIZEL) };
  622.     HRESULT hr;
  623.     SIZEL   slHiMetric;
  624.  
  625.  
  626.     // first thing to do is write out our stream hdr structure.
  627.     //
  628.     hr = pStream->Write(&streamhdr, sizeof(STREAMHDR), NULL);
  629.     RETURN_ON_FAILURE(hr);
  630.  
  631.     // the only properties we're currently persisting here are the size
  632.     // properties for this control.  make sure we do that in HiMetric
  633.     //
  634.     PixelToHiMetric(&m_Size, &slHiMetric);
  635.  
  636.     hr = pStream->Write(&slHiMetric, sizeof(slHiMetric), NULL);
  637.     return hr;
  638. }
  639.  
  640. //=--------------------------------------------------------------------------=
  641. // COleControl::InitializeNewState    [overridable]
  642. //=--------------------------------------------------------------------------=
  643. // the user can override this to initialize variables
  644. //
  645. // Output:
  646. //    BOOL        - FALSE means couldn't do it.
  647. //
  648. // Notes:
  649. //
  650. BOOL COleControl::InitializeNewState
  651. (
  652.     void
  653. )
  654. {
  655.     // we find this largely uninteresting
  656.     //
  657.     return TRUE;
  658. }
  659.  
  660.  
  661.